use crate::symbols::symbols::SymbolicExp;
use crate::symbols::traits::Derivate;
use crate::vector::items::Items;
use crate::vector::matrix::Matrix;
use uuid::Uuid;

impl Derivate for Matrix<SymbolicExp> {
    fn derivate_from_symbols(&self, symbols: SymbolicExp) -> Self {
        let binding = Uuid::new_v4().to_string();
        let key = binding.as_str();
        let data = self
            .data
            .iter()
            .map(|x| {
                Items(
                    x.iter()
                        .map(|y| {
                            symbols
                                .change_from_symbol(y.clone(), key)
                                .derivate(key)
                                .change_to_symbol(symbols.clone(), key)
                        })
                        .collect(),
                )
            })
            .collect();

        Matrix {
            rows: self.rows,
            cols: self.cols,
            data,
        }
    }

    fn derivate_by_symbols(&self, symbols: SymbolicExp) -> Self {
        let binding = Uuid::new_v4().to_string();
        let key = binding.as_str();
        let data = self
            .data
            .iter()
            .map(|x| {
                Items(
                    x.iter()
                        .map(|y| {
                            y.change_from_symbol(symbols.clone(), key)
                                .derivate(key)
                                .change_to_symbol(symbols.clone(), key)
                        })
                        .collect(),
                )
            })
            .collect();

        Matrix {
            rows: self.rows,
            cols: self.cols,
            data,
        }
    }
}
